/**
 * @description The data processing queue stores event data, and other threads fetch the data from the queue for asynchronous processing. 
 * Each data item includes a topic and data. Data with the same topic will not be processed simultaneously.
 */
import dxQueue from '../dxmodules/dxQueue.js'
import dxMap from '../dxmodules/dxMap.js'
import log from '../dxmodules/dxLogger.js'

const center = {}
// Get the service thread queue. The queue contains JSON strings in the form { topic: topic, data: data }
const queue = dxQueue.get("__SERVICE_THREAD_QUEUE");
// The map's key is the event type, i.e., topic, and the value is "Y"
const map = dxMap.get("__SERVICE_THREAD_MAP");

/**
 * Add an event to the queue
 * @param {*} topic Event type, i.e., to prevent threads from executing the same type of event simultaneously.
 * @param {*} data Event data
 */
center.push = function (topic, data) {
    queue.push(JSON.stringify({ topic: topic, data: data }))
}

/**
 * Remove an event from the queue. Events of the same type (topic) are processed synchronously, while events of different types are processed asynchronously.
 * @returns event
 */
center.pop = function () {
    try {
        let raw = queue.pop()
        if (raw === null || raw === undefined) {
            return
        }
        let rawJson = JSON.parse(raw)
        if (map.get(rawJson.topic) == "Y") {
            // If the retrieved event is running in another service thread, then push it back into the queue.
            queue.push(raw)
            return
        } else {
            map.put(rawJson.topic, "Y")
            return rawJson
        }
    } catch (error) {
        log.error(error)
    }
    return
}

/**
 * Notify queueCenter when an event is finished so that events of the same type can be executed next time.
 * @param {string} topic 
 */
center.finish = function (topic) {
    map.del(topic)
}

center.log = function () {
    log.info("Tasks currently running:", map.keys())
    log.info("Number of tasks in the queue yet to be executed:", queue.size())
}

export default center
